package com.css.fxfzysx.modules.vabStructure.service.impl;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzysx.base.attachment.service.AttachmentInfoService;
import com.css.fxfzysx.base.response.RestResponse;
import com.css.fxfzysx.constants.FxfzConstants;
import com.css.fxfzysx.constants.YNEnum;
import com.css.fxfzysx.modules.cztDataMange.constans.RedisKeyConstants;
import com.css.fxfzysx.modules.cztDataMange.entity.CpvAnalysisEntity;
import com.css.fxfzysx.modules.cztDataMange.entity.CpvInfoEntity;
import com.css.fxfzysx.modules.cztDataMange.entity.CpvResultEntity;
import com.css.fxfzysx.modules.cztDataMange.repository.BacInformationRepository;
import com.css.fxfzysx.modules.cztDataMange.service.BacInformationService;
import com.css.fxfzysx.modules.cztDataMange.utils.GenerationNumberUtil;
import com.css.fxfzysx.modules.vabStructure.entity.cztSeismicTimeHistoryEntity;
import com.css.fxfzysx.modules.vabStructure.param.CpvInfoParam;
import com.css.fxfzysx.modules.vabStructure.param.CustomVulnerabilityParam;
import com.css.fxfzysx.modules.vabStructure.repository.CustomVulnerabilityRepository;
import com.css.fxfzysx.modules.vabStructure.repository.PsvAnalysisRepository;
import com.css.fxfzysx.modules.vabStructure.service.PsvAnalysisService;
import com.css.fxfzysx.modules.vabStructure.utils.LeastSquareMethod1;
import com.css.fxfzysx.modules.vabStructure.vo.CpvAnalysisVo;
import com.css.fxfzysx.modules.vabStructure.vo.CpvInfoVO;
import com.css.fxfzysx.modules.vabStructure.vo.McVo;
import com.css.fxfzysx.util.*;
import com.css.fxfzysx.web.PlatformSessionContext;
import com.css.fxfzysx.zcpt.sys.entity.SUser;
import com.css.fxfzysx.zcpt.sys.service.SUserService;
import com.css.fxfzysx.zcpt.sys.service.SysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PsvAnalysisServiceImpl implements PsvAnalysisService {

    @Autowired
    private PsvAnalysisRepository psvAnalysisRepository;
    @Resource
    BacInformationService bacInformationService;
    @Autowired
    private SysRoleService roleService;
    @Autowired
    private BacInformationRepository bacInformationRepository;
    @Autowired
    private SUserService userService;
    @Resource
    private GenerationNumberUtil generationNumberUtil;
    @Autowired
    private CustomVulnerabilityRepository customVulnerabilityRepository;
    @Autowired
    private AttachmentInfoService attachmentInfoService;

    @Override
    public RestResponse uploadPsaData(MultipartFile file, String type) {
        try {
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            List<List<Object>> read = reader.read(1, reader.getRowCount());
            List<Object> title = reader.readRow(0);
            String titleName = "[序号, 地震动参数, 结构响应参数]";
            if (!titleName.equals(title.toString())) {
                return RestResponse.fail("导入失败，请检查表头是否改动");
            }
            if (read.size() == 0) {
                return RestResponse.fail("导入失败，表格中无数据");
            }
            //数据校验
            RestResponse rs = psaParameterVerification(read.size(), read);
            if (rs.getCode() != 200) {
                return RestResponse.fail(rs.getMessage());
            }
            ArrayList<CpvAnalysisVo> resultList = new ArrayList<>();
            for (List<Object> datum : read) {
                CpvAnalysisVo cpvAnalysisVo = new CpvAnalysisVo();
                if (type.equals("gal")) {
                    BigDecimal divide = new BigDecimal(datum.get(2).toString()).divide(BigDecimal.valueOf(980), 6, RoundingMode.HALF_UP);
                    double dataLog = Math.log(divide.doubleValue());
                    cpvAnalysisVo.setResponseParams(divide);
                    cpvAnalysisVo.setResponseParamsLog(BigDecimal.valueOf(dataLog));
                } else {
                    BigDecimal param = new BigDecimal(datum.get(2).toString());
                    double dataLog = Math.log(param.doubleValue());
                    cpvAnalysisVo.setResponseParams(param);
                    cpvAnalysisVo.setResponseParamsLog(BigDecimal.valueOf(dataLog));
                }
                double log = Math.log(new BigDecimal(datum.get(1).toString()).doubleValue());
                cpvAnalysisVo.setDzdParams(new BigDecimal(datum.get(1).toString()));
                cpvAnalysisVo.setDzdParamsLog(BigDecimal.valueOf(log));
                resultList.add(cpvAnalysisVo);
            }
            List<CpvAnalysisVo> newList = resultList.stream().sorted(Comparator.comparing(CpvAnalysisVo::getDzdParams))
                    .collect(Collectors.toList());
            return RestResponse.succeed(newList);
        } catch (IOException e) {
            String message = "导入失败!";
            log.error(message, e);
            return RestResponse.fail(message);
        }
    }

    private RestResponse psaParameterVerification(int size, List<List<Object>> data) {
        for (int i = 0; i < size; i++) {
            List<Object> objects = data.get(i);
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 2) + "行的{地震动参数}不能为空！");
            if (StringUtils.isBlank(objects.get(2).toString()))
                return RestResponse.fail("第" + (i + 2) + "行的{结构响应参数}不能为空！");
        }
        return RestResponse.succeed();
    }

    @Autowired
    private ThreadPoolUtil threadPoolUtil;

    @Override
    public RestResponse countCpvAnalysis(CpvInfoParam param) {
        CpvInfoVO vo = new CpvInfoVO();
        try {
            CpvInfoEntity entity1 = param.getEntity();
            List<CpvAnalysisEntity> list1 = param.getList1();
            List<BigDecimal> xList = new ArrayList<>();
            List<BigDecimal> yList = new ArrayList<>();

            for (CpvAnalysisEntity entity : list1) {
                xList.add(BigDecimal.valueOf(Math.log(entity.getDzdParams().doubleValue())));
                yList.add(BigDecimal.valueOf(Math.log(entity.getResponseParams().doubleValue())));
            }

            BigDecimal[] xData = xList.toArray(new BigDecimal[0]);
            BigDecimal[] yData = yList.toArray(new BigDecimal[0]);

            Map<String, BigDecimal> decimalMap = LeastSquareMethod1.leastSquareMethod1(xData, yData);
            BigDecimal a = decimalMap.get("a");
            BigDecimal b = decimalMap.get("b");
            BigDecimal rs = decimalMap.get("rs");
            BigDecimal r2 = decimalMap.get("r2");

            entity1.setParam1(a.setScale(4, BigDecimal.ROUND_HALF_UP));
            entity1.setParam2(b.setScale(4, BigDecimal.ROUND_HALF_UP));
            entity1.setParam3(rs.setScale(4, BigDecimal.ROUND_HALF_UP));
            entity1.setParam4(r2.setScale(4, BigDecimal.ROUND_HALF_UP));

            if (PlatformObjectUtils.isNotEmpty(entity1.getMcSd()) && PlatformObjectUtils.isNotEmpty(entity1.getMcMd()) && PlatformObjectUtils.isNotEmpty(entity1.getMcEd()) && PlatformObjectUtils.isNotEmpty(entity1.getMcCd())) {
                BigDecimal divide1 = BigDecimal.valueOf(Math.exp(a.doubleValue()));
                BigDecimal mSd1 = BigDecimal.valueOf(Math.pow(entity1.getMcSd().divide(divide1, 7,
                        BigDecimal.ROUND_HALF_UP).doubleValue(), BigDecimal.ONE.divide(b, 7, BigDecimal.ROUND_HALF_UP).doubleValue()));
                BigDecimal mMd1 = BigDecimal.valueOf(Math.pow(entity1.getMcMd().divide(divide1, 7,
                        BigDecimal.ROUND_HALF_UP).doubleValue(), BigDecimal.ONE.divide(b, 7, BigDecimal.ROUND_HALF_UP).doubleValue()));
                BigDecimal mEd1 = BigDecimal.valueOf(Math.pow(entity1.getMcEd().divide(divide1, 7,
                        BigDecimal.ROUND_HALF_UP).doubleValue(), BigDecimal.ONE.divide(b, 7, BigDecimal.ROUND_HALF_UP).doubleValue()));
                BigDecimal mCd1 = BigDecimal.valueOf(Math.pow(entity1.getMcCd().divide(divide1, 7,
                        BigDecimal.ROUND_HALF_UP).doubleValue(), BigDecimal.ONE.divide(b, 7, BigDecimal.ROUND_HALF_UP).doubleValue()));
                entity1.setMSd1(mSd1.setScale(4, BigDecimal.ROUND_HALF_UP));
                entity1.setMMd1(mMd1.setScale(4, BigDecimal.ROUND_HALF_UP));
                entity1.setMEd1(mEd1.setScale(4, BigDecimal.ROUND_HALF_UP));
                entity1.setMCd1(mCd1.setScale(4, BigDecimal.ROUND_HALF_UP));
            }

            if (PlatformObjectUtils.isNotEmpty(entity1.getPcSd()) && PlatformObjectUtils.isNotEmpty(entity1.getPcMd()) && PlatformObjectUtils.isNotEmpty(entity1.getPcEd()) && PlatformObjectUtils.isNotEmpty(entity1.getPcCd())) {

                BigDecimal pSd1 = BigDecimal.valueOf(Math.hypot(rs.doubleValue(), entity1.getPcSd().doubleValue()))
                        .divide(b, 4, BigDecimal.ROUND_HALF_UP);

                BigDecimal pMd1 = BigDecimal.valueOf(Math.hypot(rs.doubleValue(), entity1.getPcMd().doubleValue()))
                        .divide(b, 4, BigDecimal.ROUND_HALF_UP);
                BigDecimal pEd1 = BigDecimal.valueOf(Math.hypot(rs.doubleValue(), entity1.getPcEd().doubleValue()))
                        .divide(b, 4, BigDecimal.ROUND_HALF_UP);
                BigDecimal pCd1 = BigDecimal.valueOf(Math.hypot(rs.doubleValue(), entity1.getPcCd().doubleValue()))
                        .divide(b, 4, BigDecimal.ROUND_HALF_UP);
                entity1.setPSd1(pSd1);
                entity1.setPMd1(pMd1);
                entity1.setPEd1(pEd1);
                entity1.setPCd1(pCd1);
            }
            vo.setEntity(entity1);
            vo.setList1(list1);

            Map<String, Map<BigDecimal, BigDecimal>> mapMap = new HashMap<>();
            // 系统默认开始值0.01，终止值2，中间间隔0.05自增(用户可以修改间隔值)
            BigDecimal IM = BigDecimal.valueOf(0.01);
            BigDecimal endValue = BigDecimal.valueOf(2);
            //如果用户修改起始值、终止值   那么list中第一个就是用户输入的开始值,第二个是终止值  (逻辑修改,后台存储0.01到2，间隔值0.01)
            if (PlatformObjectUtils.isNotEmpty(entity1.getStartValue())) {
                IM = entity1.getStartValue();
            }
            if (PlatformObjectUtils.isNotEmpty(entity1.getEndValue())) {
                endValue = entity1.getEndValue();
            }

            while (IM.compareTo(endValue.add(entity1.getIntervalValue())) < 1) {
                if (IM.compareTo(endValue) > 0) {
                    IM = endValue;
                }

                Map<BigDecimal, BigDecimal> map = null;

                BigDecimal a2 = BigDecimal.valueOf(Math.log(IM.doubleValue()));
                if (PlatformObjectUtils.isNotEmpty(entity1.getMSd1()) && PlatformObjectUtils.isNotEmpty(entity1.getMMd1()) && PlatformObjectUtils.isNotEmpty(entity1.getMEd1()) && PlatformObjectUtils.isNotEmpty(entity1.getMCd1())
                        && PlatformObjectUtils.isNotEmpty(entity1.getPSd1()) && PlatformObjectUtils.isNotEmpty(entity1.getPMd1()) && PlatformObjectUtils.isNotEmpty(entity1.getPEd1()) && PlatformObjectUtils.isNotEmpty(entity1.getPCd1())) {
                    //起线程
                    int threadNum = 8;
                    ExecutorService executorService = threadPoolUtil.getFixedThreadPool(threadNum);
//                    List<Future> futureList = new ArrayList<>();
                    List<Future> futureList = Collections.synchronizedList(new ArrayList<>());
                    for (int j = 0; j < threadNum; j++) {
                        BigDecimal temp = new BigDecimal(0);
                        if (j == 0) {
                            BigDecimal subtract = a2.subtract(BigDecimal.valueOf(Math.log(entity1.getMSd1().doubleValue())));
                            temp = subtract.divide(entity1.getPSd1(), 4,
                                    BigDecimal.ROUND_HALF_UP);
                        } else if (j == 1) {
                            BigDecimal subtract = a2.subtract(BigDecimal.valueOf(Math.log(entity1.getMMd1().doubleValue())));
                            temp = subtract.divide(entity1.getPMd1(), 4,
                                    BigDecimal.ROUND_HALF_UP);
                        } else if (j == 2) {
                            BigDecimal subtract = a2.subtract(BigDecimal.valueOf(Math.log(entity1.getMEd1().doubleValue())));
                            temp = subtract.divide(entity1.getPEd1(), 4,
                                    BigDecimal.ROUND_HALF_UP);
                        } else if (j == 3) {
                            BigDecimal subtract = a2.subtract(BigDecimal.valueOf(Math.log(entity1.getMCd1().doubleValue())));
                            temp = subtract.divide(entity1.getPCd1(), 4,
                                    BigDecimal.ROUND_HALF_UP);
                        } else if (j == 4) {
                            if (PlatformObjectUtils.isNotEmpty(entity1.getMSd2()) || PlatformObjectUtils.isNotEmpty(entity1.getPSd2())) {
                                BigDecimal mSd2 = entity1.getMSd1();
                                BigDecimal pSd2 = entity1.getPSd1();
                                if (PlatformObjectUtils.isNotEmpty(entity1.getMSd2())) {
                                    mSd2 = entity1.getMSd2();
                                }
                                if (PlatformObjectUtils.isNotEmpty(entity1.getPSd2())) {
                                    pSd2 = entity1.getPSd2();
                                }
                                BigDecimal subtract = a2.subtract(BigDecimal.valueOf(Math.log(mSd2.doubleValue())));
                                temp = subtract.divide(pSd2, 4,
                                        BigDecimal.ROUND_HALF_UP);
                            } else {
                                temp = BigDecimal.ZERO;
                            }
                        } else if (j == 5) {
                            if (PlatformObjectUtils.isNotEmpty(entity1.getMMd2()) || PlatformObjectUtils.isNotEmpty(entity1.getPMd2())) {
                                BigDecimal mmd2 = entity1.getMMd1();
                                BigDecimal pmd2 = entity1.getPMd1();
                                if (PlatformObjectUtils.isNotEmpty(entity1.getMMd2())) {
                                    mmd2 = entity1.getMMd2();
                                }
                                if (PlatformObjectUtils.isNotEmpty(entity1.getPMd2())) {
                                    pmd2 = entity1.getPMd2();
                                }
                                BigDecimal subtract = a2.subtract(BigDecimal.valueOf(Math.log(mmd2.doubleValue())));
                                temp = subtract.divide(pmd2, 4,
                                        BigDecimal.ROUND_HALF_UP);
                            } else {
                                temp = BigDecimal.ZERO;
                            }
                        } else if (j == 6) {
                            if (PlatformObjectUtils.isNotEmpty(entity1.getMEd2()) || PlatformObjectUtils.isNotEmpty(entity1.getPEd2())) {
                                BigDecimal med1 = entity1.getMEd1();
                                BigDecimal ped1 = entity1.getPEd1();
                                if (PlatformObjectUtils.isNotEmpty(entity1.getMEd2())) {
                                    med1 = entity1.getMEd2();
                                }
                                if (PlatformObjectUtils.isNotEmpty(entity1.getPEd2())) {
                                    ped1 = entity1.getPEd2();
                                }
                                BigDecimal subtract = a2.subtract(BigDecimal.valueOf(Math.log(med1.doubleValue())));
                                temp = subtract.divide(ped1, 4,
                                        BigDecimal.ROUND_HALF_UP);
                            } else {
                                temp = BigDecimal.ZERO;
                            }
                        } else if (j == 7) {
                            if (PlatformObjectUtils.isNotEmpty(entity1.getMCd2()) || PlatformObjectUtils.isNotEmpty(entity1.getPCd2())) {
                                BigDecimal mcd2 = entity1.getMCd1();
                                BigDecimal pcd2 = entity1.getPCd1();
                                if (PlatformObjectUtils.isNotEmpty(entity1.getMCd2())) {
                                    mcd2 = entity1.getMCd2();
                                }
                                if (PlatformObjectUtils.isNotEmpty(entity1.getPCd2())) {
                                    pcd2 = entity1.getPCd2();
                                }
                                BigDecimal subtract = a2.subtract(BigDecimal.valueOf(Math.log(mcd2.doubleValue())));
                                temp = subtract.divide(pcd2, 4,
                                        BigDecimal.ROUND_HALF_UP);
                            } else {
                                temp = BigDecimal.ZERO;
                            }
                        }

                        Callable callable = new ReloadCallable(temp, "signal");
                        Future submit = executorService.submit(callable);
                        futureList.add(submit);
                    }
                    executorService.shutdown();


                    BigDecimal FIM1 = (BigDecimal) futureList.get(0).get();
                    BigDecimal FIM2 = (BigDecimal) futureList.get(1).get();
                    BigDecimal FIM3 = (BigDecimal) futureList.get(2).get();
                    BigDecimal FIM4 = (BigDecimal) futureList.get(3).get();

                    if (mapMap.containsKey("SD")) {
                        map = mapMap.get("SD");
                    } else {
                        map = new TreeMap<>();
                    }
                    map.put(IM, FIM1);
                    mapMap.put("SD", map);
                    if (mapMap.containsKey("MD")) {
                        map = mapMap.get("MD");
                    } else {
                        map = new TreeMap<>();
                    }
                    map.put(IM, FIM2);
                    mapMap.put("MD", map);
                    if (mapMap.containsKey("ED")) {
                        map = mapMap.get("ED");
                    } else {
                        map = new TreeMap<>();
                    }
                    map.put(IM, FIM3);
                    mapMap.put("ED", map);
                    if (mapMap.containsKey("CD")) {
                        map = mapMap.get("CD");
                    } else {
                        map = new TreeMap<>();
                    }
                    map.put(IM, FIM4);
                    mapMap.put("CD", map);


                    if (PlatformObjectUtils.isNotEmpty(entity1.getMSd2()) || PlatformObjectUtils.isNotEmpty(entity1.getPSd2())) {
                        if (mapMap.containsKey("SDL")) {
                            map = mapMap.get("SDL");
                        } else {
                            map = new TreeMap<>();
                        }
                        map.put(IM, (BigDecimal) futureList.get(4).get());
                        mapMap.put("SDL", map);
                    }


                    if (PlatformObjectUtils.isNotEmpty(entity1.getMMd2()) || PlatformObjectUtils.isNotEmpty(entity1.getPMd2())) {
                        if (mapMap.containsKey("MDL")) {
                            map = mapMap.get("MDL");
                        } else {
                            map = new TreeMap<>();
                        }
                        map.put(IM, (BigDecimal) futureList.get(5).get());
                        mapMap.put("MDL", map);
                    }


                    if (PlatformObjectUtils.isNotEmpty(entity1.getMEd2()) || PlatformObjectUtils.isNotEmpty(entity1.getPEd2())) {
                        if (mapMap.containsKey("EDL")) {
                            map = mapMap.get("EDL");
                        } else {
                            map = new TreeMap<>();
                        }
                        map.put(IM, (BigDecimal) futureList.get(6).get());
                        mapMap.put("EDL", map);
                    }


                    if (PlatformObjectUtils.isNotEmpty(entity1.getMCd2()) || PlatformObjectUtils.isNotEmpty(entity1.getPCd2())) {
                        if (mapMap.containsKey("CL")) {
                            map = mapMap.get("CL");
                        } else {
                            map = new TreeMap<>();
                        }
                        map.put(IM, (BigDecimal) futureList.get(7).get());
                        mapMap.put("CL", map);
                    }
                }
                if (IM.compareTo(endValue) == 0) {
                    break;
                }
                IM = IM.add(entity1.getIntervalValue());
//                IM = IM.add(BigDecimal.valueOf(0.01));
            }

            List<CpvResultEntity> resultList = new ArrayList<>();
            for (String key : mapMap.keySet()) {
                int sum = 1;
                Map<BigDecimal, BigDecimal> map = mapMap.get(key);
                for (Map.Entry<BigDecimal, BigDecimal> entry : map.entrySet()) {
                    CpvResultEntity entity2 = new CpvResultEntity();
                    entity2.setCpviId(entity1.getCpviId());
                    entity2.setBreakState(key);
                    entity2.setSum(sum);
                    entity2.setIm(entry.getKey().setScale(4, BigDecimal.ROUND_UP));
                    entity2.setFim(entry.getValue().setScale(4, BigDecimal.ROUND_UP));
                    resultList.add(entity2);
                    sum++;
                }
            }
            vo.setList2(resultList);
            return RestResponse.succeed(vo);
        } catch (Exception e) {
            String errorMessage = "计算失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    /**
     * 计算fai
     *
     * @param u
     */
    private static BigDecimal selfCaculate(BigDecimal u) {
        BigDecimal ret = BigDecimal.valueOf(0);
        if (u.compareTo(BigDecimal.valueOf(-3.89)) < 0) {
            return new BigDecimal(0);
        } else if (u.compareTo(BigDecimal.valueOf(3.89)) > 0) {
            return new BigDecimal(1);
        }
        BigDecimal temp = BigDecimal.valueOf(-3.89);
        while (temp.compareTo(u) < 1) {
            ret = ret.add(BigDecimal.valueOf(0.0001).multiply(fx(temp)));
            temp = temp.add(BigDecimal.valueOf(0.0001));
        }
        return ret;
    }

    private static List<BigDecimal> temp(BigDecimal ret, BigDecimal temp) {
        List<BigDecimal> bList = new ArrayList<>();
        ret = ret.add(BigDecimal.valueOf(0.0001).multiply(fx(temp)));
        temp = temp.add(BigDecimal.valueOf(0.0001));
        bList.add(0, ret);
        bList.add(1, temp);
        return bList;
    }

    private static BigDecimal fx(BigDecimal x) {
        double a = 1.0 / Math.sqrt(Math.PI * 2);
        a = a * Math.pow(Math.E, -0.5 * Math.pow(Double.parseDouble(x.toString()), 2));
        return BigDecimal.valueOf(a);
    }

    @Override
    public RestResponse saveCpvInfoEntity(CpvInfoParam param) {
        try {
            String user = userService.getSUser(PlatformSessionContext.getUserID());
            SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
            CpvInfoEntity entity = param.getEntity();
            List<CpvAnalysisEntity> CpvAnalysisList = param.getList1();
            List<CpvResultEntity> list2 = param.getList2();
            //如果这个集合为空,计算状态为未计算
            if (PlatformObjectUtils.isEmpty(list2)) {
                entity.setCalculateOrNot("0");
            } else {
                entity.setCalculateOrNot("1");
            }
            List<cztSeismicTimeHistoryEntity> seismicTimeHistoryList = param.getSeismicTimeHistoryList();

            //主表保存或修改,如果有id是修改,否则新增
            if (PlatformObjectUtils.isEmpty(entity.getCpviId())) {
                entity.setCpviId(UUIDGenerator.getUUID());
                entity.setCreateUnit(sUser.getOrgName());
                entity.setCreateUser(PlatformSessionContext.getUserID());
                entity.setDataType(FxfzConstants.CZT_GLDZ_INFO);
                entity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                entity.setBasicLibrary("0");
                entity.setDelFlag(YNEnum.N.toString());
                entity.setNumber(generationNumberUtil.getCityInitials(entity.getProvince()) +
                        generationNumberUtil.type(entity.getStructureType0(), entity.getStructureType1()) +
                        generationNumberUtil.getFs(entity.getFortification()) +
                        generationNumberUtil.getGenerationNumber(RedisKeyConstants.CZT_HD_KEY));
                bacInformationRepository.saveCpvInfoEntity(entity);
            } else {
                entity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
                entity.setUpdateUser(PlatformSessionContext.getUserID());
                entity.setCreateUnit(sUser.getOrgName());
                bacInformationRepository.updateCpvInfoEntity(entity);
            }

            //参数数据表修改或保存,此表是导入的,计算之前也会有值
            if (PlatformObjectUtils.isNotEmpty(CpvAnalysisList)) {
                for (CpvAnalysisEntity cpvAnalysisEntity : CpvAnalysisList) {
                    if (PlatformObjectUtils.isNotEmpty(cpvAnalysisEntity.getCpvaId())) {
                        cpvAnalysisEntity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
                        cpvAnalysisEntity.setUpdateUser(PlatformSessionContext.getUserID());
                        bacInformationRepository.updatePsaData(cpvAnalysisEntity);
                    } else {
                        cpvAnalysisEntity.setCpviId(entity.getCpviId());
                        cpvAnalysisEntity.setCpvaId(UUIDGenerator.getUUID());
                        cpvAnalysisEntity.setCreateUser(PlatformSessionContext.getUserID());
                        cpvAnalysisEntity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                        cpvAnalysisEntity.setDelFlag(YNEnum.N.toString());
                        bacInformationRepository.savePsaData(cpvAnalysisEntity);
                    }
                }
            }

            if (PlatformObjectUtils.isNotEmpty(seismicTimeHistoryList)) {
                seismicTimeHistoryList.forEach(it -> {
                    it.setCpviId(entity.getCpviId());
                    it.setId(UUIDGenerator.getUUID());
                    it.setDelFlag("0");
                    bacInformationRepository.saveSeismicTimeHistory(it);
                });
            }

            //IM表保存,保存之后不能修改,没计算就没数据所以用不到修改
            if (PlatformObjectUtils.isNotEmpty(list2)) {
                list2.forEach(it -> {
                    it.setCpviId(entity.getCpviId());
                    it.setCpvrId(UUIDGenerator.getUUID());
                    it.setCreateUser(PlatformSessionContext.getUserID());
                    it.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                    it.setDelFlag(YNEnum.N.toString());
                    bacInformationRepository.saveCpvResultEntity(it);
                });
            }
            return RestResponse.succeed("保存成功");
        } catch (Exception e) {
            String errorMessage = "保存失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    @Override
    public RestResponse saveCpvAnalysis(List<CpvAnalysisEntity> list) {
        for (CpvAnalysisEntity entity : list) {
            bacInformationService.saveCpvAnalysis(entity);
        }
        return RestResponse.succeed("保存成功！");
    }

    @Override
    public RestResponse saveCpvResultEntity(List<Map<String, Object>> mapList) {
        return null;
    }

    @Override
    public RestResponse getById(String id) {
        JSONObject jsonObject = new JSONObject();
        CpvInfoEntity entity = bacInformationService.getCpvInfoEntityById(id);
        if (PlatformObjectUtils.isNotEmpty(entity.getSrvId())) {
            entity.setSrvName(attachmentInfoService.getAttach(entity.getSrvId()).getAttachName());
        }
        if (PlatformObjectUtils.isNotEmpty(entity.getGmrcpId())) {
            entity.setGmrcpName(attachmentInfoService.getAttach(entity.getGmrcpId()).getAttachName());
        }
        jsonObject.put("entity", entity);
        List<CpvAnalysisEntity> list1 = bacInformationService.getCpvAnalysisEntityByCpviId(id);
        jsonObject.put("list1", list1);
//        List<Map<String, Object>> mapList = new ArrayList<>();
        List<CpvResultEntity> list2 = bacInformationService.getCpvResultEntityByCpviId(id);
//        for (CpvResultEntity entity2 : list2) {
//            String jsonData = entity2.getJsonData();
//            Map<String, Object> map = JSONObject.parseObject(jsonData);
//            map.put("cpvrId", entity2.getCpvrId());
//            map.put("cpviId", entity2.getCpviId());
//            map.put("breakState", entity2.getBreakState());
//            mapList.add(map);
//        }
        jsonObject.put("list2", list2);
        return RestResponse.succeed(jsonObject);
    }

    @Override
    public RestResponse queryCpvAnalysis(CpvInfoEntity cpvInfoEntity, HttpServletRequest request) {
        try {
            int page = Integer.valueOf(request.getParameter(PlatformPageUtils.CUR_PAGE));
            int size = Integer.valueOf(request.getParameter(PlatformPageUtils.PAGE_SIZE));
            String userID = PlatformSessionContext.getUserID();
            String role = roleService.getRoleByUserId(userID);
            List<Map> roleMaps = JSONObject.parseArray(role, Map.class);
            for (Map roleMap : roleMaps) {
                String roleCode = (String) roleMap.get("roleCode");
                if (roleCode.equals(FxfzConstants.CZT_PRI_GL_ROLE) || roleCode.equals(FxfzConstants.CZT_COUN_GL_ROLE)) {
                    cpvInfoEntity.setRole("0");
                } else {
                    cpvInfoEntity.setRole("1");
                }
            }
            return RestResponse.succeed(psvAnalysisRepository.queryCpvAnalysis(cpvInfoEntity, page, size));
        } catch (Exception e) {
            String errorMessage = "查看失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    @Override
    public RestResponse uploadMcData(MultipartFile file) {
        try {
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            List<List<Object>> read = reader.read(2, reader.getRowCount());
            List<Object> title = reader.readRow(0);
            String titleName = "[序号, 类别, 轻微(SD), 中等(MD), 严重(ED), 倒塌(Collapse)]";
            if (!titleName.equals(title.toString())) {
                return RestResponse.fail("导入失败，请检查表头是否改动");
            }
            if (read.size() == 0) {
                return RestResponse.fail("导入失败，表格中无数据");
            }
            if (read.size() != 2) {
                return RestResponse.fail("导入失败，只能导入两条数据");
            }
            //数据校验
            RestResponse rs = psaParameterMc(read.size(), read);
            if (rs.getCode() != 200) {
                return RestResponse.fail(rs.getMessage());
            }
            McVo mcVo = new McVo();
            for (List<Object> datum : read) {
                if (datum.get(1).toString().equals("mc")) {
                    mcVo.setMcEd(new BigDecimal(datum.get(2).toString()));
                    mcVo.setMcMd(new BigDecimal(datum.get(3).toString()));
                    mcVo.setMcSd(new BigDecimal(datum.get(4).toString()));
                    mcVo.setMcCd(new BigDecimal(datum.get(5).toString()));
                } else {
                    mcVo.setPcSd(new BigDecimal(datum.get(2).toString()));
                    mcVo.setPcMd(new BigDecimal(datum.get(3).toString()));
                    mcVo.setPcEd(new BigDecimal(datum.get(4).toString()));
                    mcVo.setPcCd(new BigDecimal(datum.get(5).toString()));
                }
            }
            return RestResponse.succeed(mcVo);
        } catch (IOException e) {
            String message = "导入失败!";
            log.error(message, e);
            return RestResponse.fail(message);
        }
    }

    private RestResponse psaParameterMc(int size, List<List<Object>> data) {
        for (int i = 0; i < size; i++) {
            List<Object> objects = data.get(i);
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 2) + "行的{类别}不能为空！");
            if (StringUtils.isBlank(objects.get(2).toString()))
                return RestResponse.fail("第" + (i + 2) + "行的{轻微(SD)}不能为空！");
            if (StringUtils.isBlank(objects.get(2).toString()))
                return RestResponse.fail("第" + (i + 2) + "行的{中等(MD)}不能为空！");
            if (StringUtils.isBlank(objects.get(2).toString()))
                return RestResponse.fail("第" + (i + 2) + "行的{严重(ED)}不能为空！");
            if (StringUtils.isBlank(objects.get(2).toString()))
                return RestResponse.fail("第" + (i + 2) + "行的{倒塌(Collapse)}不能为空！");
        }
        return RestResponse.succeed();
    }

    class ReloadCallable implements Callable<Object> {
        private BigDecimal value;
        private BigDecimal temp;
        private String type;

        ReloadCallable(BigDecimal value, String type) {
            this.value = value;
            this.type = type;
        }

        ReloadCallable(BigDecimal value, BigDecimal temp, String type) {
            this.type = type;
            this.value = value;
            this.temp = temp;
        }

        @Override
        public Object call() throws Exception {
            if ("signal".equals(type)) {
                return selfCaculate(value);
            } else if ("for".equals(type)) {
                return temp(value, temp);
            } else if ("temp".equals(type)) {
                return fx(value);
            }
            return null;
        }
    }

    @Override
    public RestResponse moveBasicLibrary(CustomVulnerabilityParam param) {
        try {
            if (param.getOperate().equals("0")) {
                psvAnalysisRepository.moveBasicLibrary(param.getId(), param.getOperate());
            } else {
                Integer count = customVulnerabilityRepository.queryBasicLibrary(param);
                if (count != 0) {
                    return RestResponse.fail("失败,存在重复数据!");
                } else {
                    psvAnalysisRepository.moveBasicLibrary(param.getId(), param.getOperate());
                }
            }
            return RestResponse.succeed("成功!");
        } catch (Exception e) {
            String errorMessage = "失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    @Override
    public void exportExcel(HttpServletResponse response, String cpviId) {
        try {
            List<CpvAnalysisEntity> dataList = bacInformationService.getCpvAnalysisEntityByCpviId(cpviId);
            FileUtil.exportExcel(dataList, "地震动参数数据", "地震动参数数据", CpvAnalysisEntity.class, "地震动参数数据", response);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    @Override
    public RestResponse importSeismicTimeHistory(MultipartFile file) {
        try {
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            List<List<Object>> read = reader.read(1, reader.getRowCount());
            List<Object> title = reader.readRow(0);
            log.info(title.toString());
            String titleName = "[时间/s, 加速度/cm/s/s]";
            if (!titleName.equals(title.toString())) {
                return RestResponse.fail("导入失败，请检查表头是否改动");
            }
            if (read.size() == 0) {
                return RestResponse.fail("导入失败，表格中无数据");
            }
            //数据校验
            RestResponse rs = psaSeismicTimeHistory(read.size(), read);
            if (rs.getCode() != 200) {
                return RestResponse.fail(rs.getMessage());
            }
            ArrayList<cztSeismicTimeHistoryEntity> list = new ArrayList<>();
            for (List<Object> objects : read) {
                cztSeismicTimeHistoryEntity entity = new cztSeismicTimeHistoryEntity();
                entity.setTime(Double.parseDouble(objects.get(0).toString()));
                entity.setDisplacementResponse(Double.parseDouble(objects.get(1).toString()));
                list.add(entity);
            }
            return RestResponse.succeed(list);
        } catch (IOException e) {
            String errorMessage = "导入失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    private RestResponse psaSeismicTimeHistory(int size, List<List<Object>> data) {
        for (int i = 0; i < size; i++) {
            List<Object> objects = data.get(i);
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 1) + "行的{时间/s}不能为空！");
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 2) + "行的{加速度/cm/s/s}不能为空！");
        }
        return RestResponse.succeed();
    }
}
